using System;
using System.Text;
using System.Reflection;
using System.Collections.Generic;

using Crainiate.Data.Persistence.Providers;

namespace Crainiate.Data.Persistence.Providers.Remoting
{
    //Remote dispatcher single call object
    //Used to communicate between a remote and actual reference objects
    public class RemoteManager: MarshalByRefObject
    {
        #region Interface

        public virtual Command CreateCommand(RemoteContext context)
        {
            return new RemoteCommand(context);
        }

        public virtual Concurrency CreateConcurrency(RemoteContext context)
        {
            Context actualContext = RemoteProviderConfiguration.Instance.ResolveContext(context);
            return actualContext.CreateConcurrency();
        }

        public virtual IPersistable CreatePersistable(Type type, RemoteContext context)
        {
            Context actualContext = RemoteProviderConfiguration.Instance.ResolveContext(context);
            return actualContext.CreatePersistable(type);
        }

        public virtual IPersistable Select(IPersistable graph, RemoteContext context)
        {
            Context actualContext = RemoteProviderConfiguration.Instance.ResolveContext(context);
            Command command = actualContext.CreateCommand();
            command.Context = actualContext;

            command.Select(graph);

            return graph;
        }

        public virtual IPersistable Insert(IPersistable graph, RemoteContext context)
        {
            Context actualContext = RemoteProviderConfiguration.Instance.ResolveContext(context);
            Command command = actualContext.CreateCommand();
            command.Context = actualContext;

            command.Insert(graph);

            return graph;
        }

        public virtual IQuery Execute(IQuery query, RemoteContext context)
        {
            Context actualContext = RemoteProviderConfiguration.Instance.ResolveContext(context);
            Command command = actualContext.CreateCommand();
            command.Context = actualContext;

            command.Execute(query);

            return query;
        }

        public virtual IPersistable Update(IPersistable graph, RemoteContext context)
        {
            Context actualContext = RemoteProviderConfiguration.Instance.ResolveContext(context);
            Command command = actualContext.CreateCommand();
            command.Context = actualContext;

            command.Update(graph);

            return graph;
        }

        public virtual IPersistable Delete(IPersistable graph, RemoteContext context)
        {
            Context actualContext = RemoteProviderConfiguration.Instance.ResolveContext(context);
            Command command = actualContext.CreateCommand();
            command.Context = actualContext;

            command.Delete(graph);

            return graph;
        }

        public virtual bool Exists(IPersistable graph, RemoteContext context)
        {
            Context actualContext = RemoteProviderConfiguration.Instance.ResolveContext(context);
            Command command = actualContext.CreateCommand();
            command.Context = actualContext;
            return command.Exists(graph);
        }

        public virtual IPersistable Promote(IPersistable graph, RemoteContext context)
        {
            Context actualContext = RemoteProviderConfiguration.Instance.ResolveContext(context);
            Command command = actualContext.CreateCommand();
            command.Context = actualContext;
            
            command.Promote(graph);

            return graph;
        }

        public virtual IPersistable Demote(IPersistable graph, RemoteContext context)
        {
            Context actualContext = RemoteProviderConfiguration.Instance.ResolveContext(context);
            Command command = actualContext.CreateCommand();
            command.Context = actualContext;

            command.Demote(graph);

            return graph;
        }

        #endregion
    }
}
